package com.hb.config;

import com.hb.Product;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
    /**
     * 配置 Redis 连接工厂 JedisConnectionFactory bean
     * 通过默认构造器创建的连接工厂会向 localhost 上的 6379 端口创建连接，并且没有密码。
     * @return
     */
    @Bean
    @Primary
    public RedisConnectionFactory redisConnectionFactory() {
        return new JedisConnectionFactory();
    }

    /**
     * 如果你的 Redis 服务器运行在其他的主机或端口上，在创建连接工厂的时候，可以设置这些属性
     * @return
     */
    @Bean
    public RedisConnectionFactory redisCF() {
        JedisConnectionFactory cf = new JedisConnectionFactory();
        cf.setHostName("redis-server");
        cf.setPort(7379);
        // 类似地，如果你的 Redis 服务器配置为需要客户端认证的话，那么可以通过调用 setPassword() 方法来设置密码
        cf.setPassword("foobared");
        return cf;
    }

    /**
     * 如果你选择使用其他连接工厂的话，只需进行简单地替换就可以了。所有的 Redis 连接工厂都具有 setHostName()、setPort() 和 setPassword() 方法。
     * 这样，它们在配置方面实际上是相同的。
     * @return
     */
    @Bean
    public RedisConnectionFactory lettuceCF() {
        LettuceConnectionFactory cf = new LettuceConnectionFactory();
        cf.setHostName("redis-server");
        cf.setPort(7379);
        cf.setPassword("foobared");
        return cf;
    }

    /**
     * 但是如果你经常使用 RedisTemplate 或 StringRedisTemplate 的话，你可以考虑将其配置为 bean，然后注入到需要的地方。
     * @param cf
     * @return
     */
    @Bean
    public RedisTemplate<String, Product> redisTemplate(RedisConnectionFactory cf) {
        RedisTemplate<String, Product> redis = new RedisTemplate<>();
        redis.setConnectionFactory(cf);
        // 设置 key 序列化器
        redis.setKeySerializer(new StringRedisSerializer());
        // 设置 value 序列化器
        redis.setValueSerializer(new Jackson2JsonRedisSerializer<Product>(Product.class));
        return redis;
    }

    /**
     * 配置 StringRedisTemplate bean
     * @param cf
     * @return
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory cf) {
        return new StringRedisTemplate(cf);
    }
}
